<!--
 * @Author: GuitarXiaohe 2205227953@qq.com
 * @Date: 2024-06-28 09:31:15
 * @LastEditors: GuitarXiaohe 2205227953@qq.com
 * @LastEditTime: 2024-06-28 14:30:50
 * @Description: 根据vxe组件封装 改写原有的API方法 手写魔改提升性能及兼容性和更简单的枚举
-->
<script setup name="p-table">
/**
 * !!当前组件配置字段多 请认真查看配置项
 * !!此组件主要用于列表
 * !!部分配置项存在冲突请仔细查看配置项的注释与方法判断
 */
import { computed } from "vue";
import Sortable from "sortablejs";
import VXETable from "vxe-table";

/**
 * vue3实例
 */
const { proxy } = getCurrentInstance();

/**
 * 配置项 传值
 */
const props = defineProps({
  // 列表主键id（必须设置且自动带出）
  keyId: {
    type: String,
    default: "id",
  },
  // 列表每一行 不限制Array对象里的类型
  data: {
    required: true,
    type: Array,
    default: () => [],
  },
  /**
   *  列表每一列
   * @param { string} label 表头
   * @param { string} prop 字段变量
   * @param { boolean} showText 文字溢出是否需要显示文字（非必填）
   * @param { string} width 宽度
   * @param { string} fixed 固定列
   */
  column: {
    required: true,
    type: Array,
    default: () => [],
  },
  /**
   * 是否展开
   */
  defaultExpandAll: {
    type: Boolean,
    default: false,
  },
  /**
   * 是否需要筛选
   */
  isScreen: {
    type: Boolean,
    default: true,
  },
  /**
   * !!弃用
   * 拖动class（需要提供本身或上级calss）
   */
  className: {
    type: String,
    default: "",
    required: false,
  },
  /**
   * 加载状态
   */
  loading: {
    type: Boolean,
    default: false,
    required: false,
  },
  /**
   * 分页总量
   */
  total: {
    type: String || Number,
    default: 0,
    required: false,
  },
  /**
   * 高度
   */
  height: {
    type: String,
    default: "640px",
    required: false,
  },
  /**
   * 值为空是 显示
   */
  empty: {
    type: String,
    default: "--",
    required: false,
  },
  /**
   * 是否需要序号
   */
  index: {
    type: Boolean,
    default: true,
    required: false,
  },
  /**
   * 是否需要复选
   */
  isSel: {
    type: Boolean,
    default: true,
  },
  /**
   * 是否需要边框
   */
  border: {
    type: Boolean,
    default: true,
  },
  /**
   * 是否需要合计
   */
  summary: {
    type: Boolean,
    default: false,
  },
  /**
   * 合计key数组 传入后自动计算
   */
  amountList: {
    type: Array,
    default: () => [],
  },
  /**
   * 如果需要自己调整合计 请传入summaryMethodYes true
   */
  summaryMethodYes: {
    type: Boolean,
    default: false,
  },
  /**
   * 合计计算 (自调用 带出一个对象值)
   */
  summaryMethod: {
    type: Function,
    default: () => [],
  },
  /**
   * 是否需要展示合计
   */
  isShowSummary: {
    type: Boolean,
    default: true,
  },
  /**
   * 是否需要斑马线
   */
  stripe: {
    type: Boolean,
    default: true,
  },
  /**
   * 是否需要树结构
   */
  isTree: {
    type: Boolean,
    default: false,
  },

  /**
   * !!（与多选二选一）
   * 是否需要单选
   */
  isRadio: {
    type: Boolean,
    default: false,
  },
  /**
   * !!注：展开行不能用于虚拟滚动
   * 是否需要展开行
   */
  isExpand: {
    type: Boolean,
    default: false,
  },
  /**
   * 是否需要分页
   */
  isPage: {
    type: Boolean,
    default: true,
  },
  /**
   * 数据总量
   */
  total: {
    required: true,
    type: [Number, String],
  },
  /**
   * 页数
   */
  page: {
    type: Number,
    default: 1,
  },
  /**
   * 每页数量
   */
  limit: {
    type: Number,
    default: 10,
  },
  /**
   * 默认给出选项每页页数
   */
  pageSizes: {
    type: Array,
    default() {
      return [10, 20, 30, 40, 50, 100, 200, 300, 500, 1000, 2000];
    },
  },
  /**
   * 移动端页码按钮的数量端默认值5
   */
  pagerCount: {
    type: Number,
    default: document.body.clientWidth < 992 ? 5 : 7,
  },
  /**
   * element 官方配置
   */
  layout: {
    type: String,
    default: "total, sizes, prev, pager, next, jumper",
  },
  /**
   * 是否需要背景色
   */
  background: {
    type: Boolean,
    default: true,
  },
  /**
   * 是否分页后触发回滚
   */
  autoScroll: {
    type: Boolean,
    default: true,
  },
  /**
   * 是否隐藏分页器
   */
  hidden: {
    type: Boolean,
    default: false,
  },
  /**
   * 是否需要传入编辑方法
   */
  isEdit: {
    type: Boolean,
    default: false,
  },
  /**
   * !! 个人不推荐此组件使用 此组件作为主列表使用 除非产品非要
   * 编辑函数 (自调用 带出一个对象值)
   */
  editMethod: {
    type: Function,
    default: () => {},
  },
});

/**
 * 实例
 */
const tableRef = ref(null);

/**
 * 注册事件名称
 */
const emit = defineEmits([
  "cell-change",
  "current-change",
  "change",
  "listChange",
]);

/**
 * 异常说明
 */
const errorMsg = reactive({
  1: "传入数据类型错误,类型应为数组!",
  2: '传入"column"数据错误,prop属性不能重复!',
  3: "当isRadio启用时,必须传入keyId作为唯一标识!",
  4: `当前keyId为${props.keyId},获取不到主键ID,请传入正确keyId`,
});

/**
 * !! 取反设置白名单
 * 白名单 判断是否需要 show-overflow-tooltip
 * 一般 操作按钮 开关 标签不需要show-overflow-tooltip 就设置白名单
 * 可设置prop为这些参数,或者设置label同样效果
 */
const whiteList = ref(["x", "操作", "状态"]);

/**
 * 全选
 * 复选勾选
 * 加入uuid 加入下标 index
 * 反馈父级组件 change
 * @param {*} result
 */
const selectAllChangeEvent = ({ checked }) => {
  const $table = tableRef.value;
  // 判断是否拿到组件实例 增加兼容
  if ($table) {
    // 获取全部的数据
    const records = $table.getCheckboxRecords();
    try {
      // 扩展使用 目前   arr = records 无作用
      arr = records;
      // 判断keyId是否正确 不正确给出异常 但不影响功能运转
      const resultId = records.every((t) => t[props.keyId]);
      if (!resultId) {
        emit("change", {
          ids: [],
          uids: records.map((item) => item["uid"]),
          index: records.map((item) => item["index"]),
          row: records,
        });
        throw errorMsg["4"];
      }

      // 判断通过增加ids
      emit("change", {
        ids: records.map((item) => item[props.keyId]),
        index: records.map((item) => item["index"]),
        uids: records.map((item) => item["uid"]),
        row: records,
      });
    } catch (err) {
      throw "p-table组件:" + err;
    }
  }
};

/**
 * 复选勾选
 * 加入uuid 加入下标 index
 * map出 id（数组）
 * 反馈父级组件 change
 * @param {*} result
 * @param {object} result
 * @return {object}{}
 */
const selectionChange = (result) => {
  const row = result.records;
  arr = row;
  try {
    // 判断keyId是否正确
    const resultId = row.every((t) => t[props.keyId]);
    // 判断keyId是否正确 不正确给出异常 但不影响功能运转

    if (!resultId) {
      emit("change", {
        ids: "",
        uids: row.map((item) => item["uid"]),
        index: row.map((item) => item["index"]),
        row: row,
      });
      throw errorMsg["4"];
    }
    // 判断通过增加ids
    emit("change", {
      ids: row.map((item) => item[props.keyId]),
      index: row.map((item) => item["index"]),
      uids: row.map((item) => item["uid"]),
      row: row,
    });
  } catch (err) {
    throw "p-table组件:" + err;
  }
};

/**
 * 点击数据一行 反馈父级触发事件 cell-change
 * @param {object} result
 */
let arr = [];
const currentChange = (result) => {
  const selection = result.row;
  // 扩展使用 目前未使用改代码  arr = selection 等待场景
  arr = selection;
  //proxy.$refs.tableRef.toggleCheckboxRow(selection);
  //emit("change", { ids: selection[props.keyId], row: selection });
  emit("cell-change", { ids: selection[props.keyId], row: selection });
};

/**
 * 单选勾选
 * @param {object} result
 */
const radioChangeEvent = (result) => {
  const selection = result.row;
  try {
    // 点击一行时触发
    // emit("current-change", { ids: selection[props.keyId], row: selection });
    // 如果不是单选 禁止 以下操作
    if (!props.isRadio) return;
    emit("change", { ids: selection[props.keyId], row: selection });
  } catch (err) {
    throw "p-table组件:" + err;
  }
};

/**
 * 筛选 是否有重复 prop（当前停用校验，开发环境容易造成浏览器卡死）
 */
const tableColumn = computed(() => {
  // const newData = Array.from(new Set(props.column.map((t) => t.prop)));
  // 取消限制重复prop

  return props.column;
});

/**
 * 数据为空的时候做出显示 给予提示
 * @param {object} val
 * @param {string} key
 * @param {string} label
 */
const getData = (val, key, label) => {
  try {
    // 判断是否有值 有值返回当前值
    if (val && key && val[key] != null && val[key] != undefined) {
      return val[key];
    } else {
      // 没有值给出提示
      if (props.empty) {
        return props.empty;
      } else if (!key) {
        return `" ${label} " 的 "prop" 为空`;
      } else {
        return `" ${label} "为空, ${key} -> " ${val[key]} "`;
      }
    }
  } catch (err) {
    throw "p-table组件:" + err;
  }
};

/**
 * 降低耦合度
 * 提高容错率
 * 数据校验
 * 判断是否类型错误或者字段重复
 * 加入uuid作为唯一标识（后端未返回id时通过uuid或下标查找数据）
 */
const list = computed(() => {
  if (!Array.isArray(props.data)) {
    throw "p-table组件:" + errorMsg["1"];
  } else {
    // 单选时,数据刷新默认选中一项
    if (props.data.length > 0 && props.isRadio) {
      const obj = props.data[0];
      // 如果为空 抛出异常
      if (!obj[props.keyId]) {
        throw "p-table组件:" + errorMsg["4"];
      }
      // emit("change", { ids: null, id: obj[props.keyId], row: obj });
    }
    // 数据参入uuid
    props.data.forEach((t, ind) => (t["index"] = ind));

    return props.data || [];
  }
});

/**
 * 判断是否需要 show-overflow-tooltip 根据白名单设定（whiteList）
 */
const isShowText = (val) => {
  if (val.label == "备注") {
    return true;
  } else if (val.label == "辅助属性") {
    return false;
  } else if (
    whiteList.value.includes(val.label) ||
    whiteList.value.includes(val.prop) ||
    val.prop.length < 2
  ) {
    return false;
  } else {
    return true;
  }
};

/**
 * 判断是否需要 fixed 表格操作栏默认给fixed  当前默认出现操作给操作栏
 */
const getFixed = (columnItem) => {
  if (columnItem.fixed) {
    return columnItem.fixed;
  } else if (columnItem.label == "操作") {
    return "right";
  } else {
    return "";
  }
};

/**
 * 合计使用 （分离方法）
 */
const sumNum = (list, field) => {
  let count = 0;
  list.forEach((item) => (count += Number(item[field])));
  return count;
};

/**
 * 合计计算 传入数组 包含字段 自动匹配生成集合栏 (吊的一批的功能，真佩服我)
 * @param {object} param
 */
const getSummaries = (param) => {
  try {
    // summaryMethodYes为true则自己通过 summaryMethod 函数在主页面执行并返回
    if (props.summaryMethodYes) {
      return props.summaryMethod(param);
    } else {
      // 通过 amountList 掺入的数组 自动计算
      if (!Array.isArray(props.amountList))
        return proxy.warningMsg(
          "p-table组件:合计计算数组传递类型错误 ==>" + props.amountList
        );
      const { columns, data } = param;
      const titleArr = columns;
      // if (!isShowSummary) return
      // const titleArr = columns.filter(t => t.title) //不能过滤
      return [
        titleArr.map((t, ind) => {
          if (ind === 0) return "合计";
          if (props.amountList.includes(t.field)) {
            return sumNum(data, t.field);
          } else {
            return "/";
          }
        }),
      ];
    }
  } catch (err) {
    throw "p-table组件:" + err;
  }
};

/**
 * 提取和赋值分页 页数
 */
const currentPage = computed({
  get() {
    return props.page;
  },
  set(val) {
    emit("update:page", val);
  },
});

/**
 * 提取和赋值每页数量 每页数量
 */
const pageSize = computed({
  get() {
    return props.limit;
  },
  set(val) {
    emit("update:limit", val);
  },
});

/**
 * 分页器变化时 反馈父级组件出发事件 并返回当前页码 尝试把列表强制移动到最上方
 * @param {number} val 改变后的值
 */
function handleSizeChange(val) {
  if (currentPage.value * val > totalCon) {
    currentPage.value = 1;
  }
  emit("pagination", { page: currentPage.value, limit: val });
  if (props.autoScroll) {
    scrollTo(0, 800);
  }
}

/**
 * 分页器变化时
 * @param {number} val 改变后的值
 */
function handleCurrentChange(val) {
  emit("pagination", { page: val, limit: pageSize.value });
  if (props.autoScroll) {
    scrollTo(0, 800);
  }
}

/**
 * 表格拖动
 * 创建拖拽实例 （停用）
 */
const initSort = () => {
  if (!props.className) return;
  console.log(props.className, "props.className");
  const table = document.querySelector(
    `.${props.className} .el-table__body-wrapper tbody`
  );
  Sortable.create(table, {
    group: "shared",
    animation: 150,
    easing: "cubic-bezier(1, 0, 0, 1)",
    onStart: () => {},
    // 结束拖动事件
    onEnd: async ({ newIndex, oldIndex }) => {
      setNodeSort(list.value, oldIndex, newIndex);
    },
  });
};

/**
 * 拖拽完成修改数据排序（暂时停用）
 */
const setNodeSort = (data, oldIndex, newIndex) => {
  const currRow = data.splice(oldIndex, 1)[0];
  data.splice(newIndex, 0, currRow);

  emit("listChange", list.value);
};

/**
 * 由于后端返回数量类型可能会不准确，所以强制 转int 增加容错
 */
const totalCon = computed(() => Number(props.total));

// 排序表头 ---------------SAT-------------------->
// const lostShow = ref(false);
// const lostData = ref([]);

// const drop = (e) => {
//   console.log(e);
// };

// const allowDrop = (e) => {
//   console.log(e);
// };

// const drag = (e) => {
//   console.log(e);
// };

/**
 * 是否开启表格编辑 当前方法暂时停用 不适合性能
 * @param {*} columnItem
 */
const editRender = (columnItem) => {
  // 如果存在autofocus为true则开启表格编辑
  if (columnItem.autofocus) {
    return {
      autofocus: ".vxe-input--inner",
      placeholder: `请双击输入${columnItem.label}`,
    };
  } else {
    return null;
  }
};

/**
 * 表格编辑方法（可以拿到编辑行的数据） 当前方法暂时停用 不适合性能
 */
const editClosedEvent = (parms) => {
  // 是否传入表格编辑方法
  if (props.isEdit) {
    //vuextable的ref，从这里传入然后在组件外拿即可（组件外不用定义ref）
    parms.tableRef = tableRef.value;
    return props.editMethod(parms);
  } else {
    const { row, column } = parms;
    const $table = tableRef.value;
    if ($table) {
      const field = column.field;
      const cellValue = row[field];
      // 判断单元格值是否被修改
      if ($table.isUpdateByRow(row, field)) {
        setTimeout(() => {
          VXETable.modal.message({
            content: `局部保存成功！ ${field}=${cellValue}`,
            status: "success",
          });
          // 局部更新单元格为已保存状态
          $table.reloadRow(row, null, field);
        }, 300);
      }
    }
  }
};

//改变合计颜色(暂时不用，但是先补充)
const footerCellClassName2 = (parms) => {
  console.log(parms, "parms");
  const { $rowIndex, columnIndex, itemIndex } = parms;
  console.log($rowIndex, "rowIndex");
  console.log(columnIndex, "columnIndex");
  if (itemIndex == 0) {
    return "col-red";
  }
};

// 排序表头 ---------------ENT-------------------->
const checkColumnMethod = ({ column }) => {
  if (column.field === "role") {
    return false;
  }
  return true;
};

/**
 * 改变列宽度时 做出改变
 */
const resizableChangeEvent = () => {
  const columns = proxy.$refs.tableRef.getColumns();
  const customData = columns.map((column) => {
    return {
      width: column.renderWidth,
    };
  });
};
// 选择视图时机
nextTick(() => {
  // 手动将表格和工具栏进行关联
  if (proxy.$refs.xToolbar1) {
    proxy.$refs.tableRef.connect(proxy.$refs.xToolbar1);
  }
});

/**
 * 
 *  :menu-config="tableMenu"
      :keyboard-config="{
        isArrow: true,
        isDel: true,
        isEnter: true,
        isTab: true,
        isEdit: true,
        isChecked: true,
      }"
 * 
 * 测试没启用
 */
const tableMenu = {
  body: {
    options: [
      [
        {
          code: "copy",
          name: "复制",
          prefixIcon: "vxe-icon-copy",
          disabled: false,
        },
        { code: "remove", name: "删除", disabled: false },
        {
          code: "save",
          name: "保存",
          prefixIcon: "vxe-icon-save",
          disabled: false,
        },
      ],
    ],
  },
};

/**
 * 展开所有 （树结构）
 */
const setAllTreeExpand = () => {
  proxy.$refs.tableRef.setAllTreeExpand(true);
};

/**
 * 关闭所有 （树结构）
 */
const clearTreeExpand = () => {
  proxy.$refs.tableRef.clearTreeExpand();
};

/**
 * 暴露
 */
defineExpose({
  setAllTreeExpand,
  clearTreeExpand,
});

/**
 * 开发环境判断
 */
const isShow = computed(() => import.meta.env.VITE_APP_ENV == "development");
</script>

<template>
  <div class="p-table">
    <div class="p-table-header">
      <div>
        <!-- 按钮插槽 -->
        <slot name="buttons" />
      </div>
      <vxe-toolbar
        ref="xToolbar1"
        custom
        v-if="props.isScreen && tableColumn.length > 10"
      />
    </div>

    <vxe-table
      ref="tableRef"
      :keyId="props.keyId"
      :id="props.keyId"
      class="tableClass"
      :column-config="{ resizable: true }"
      :row-config="{ isHover: true }"
      data-lazy
      auto-resize
      row-key
      :loading="props.loading"
      :loading-config="{
        icon: 'vxe-icon-indicator roll',
        text: '正在拼命加载中...',
      }"
      :height="props.height"
      :stripe="props.stripe && !isTree"
      :border="props.border && !isTree"
      :scroll-y="{ enabled: true, gt: 10 }"
      :scroll-x="{ enabled: true, gt: 5 }"
      :show-summary="props.amountList.length > 0"
      :data="list"
      :default-expand-all="defaultExpandAll"
      :show-footer="props.summary"
      keep-source
      resizable
      :footer-method="getSummaries"
      @checkbox-change="selectionChange"
      @cell-click="currentChange"
      @radio-change="radioChangeEvent"
      @checkbox-all="selectAllChangeEvent"
      :edit-config="{ trigger: 'dblclick', mode: 'cell', showStatus: true }"
      @edit-closed="editClosedEvent"
      :custom-config="{ storage: true, checkMethod: checkColumnMethod }"
      @resizable-change="resizableChangeEvent"
    >
      <!-- 改变合计颜色方法 -->
      <!--  :footer-cell-class-name="footerCellClassName2" -->
      <!-- 是否多选 -->
      <vxe-column
        v-if="isSel && !isRadio"
        type="checkbox"
        width="55"
        :fixed="props.isExpand ? null : 'left'"
        align="center"
      />
      <!-- 是否单选 -->
      <vxe-column
        v-if="isRadio"
        :fixed="props.isExpand ? null : 'left'"
        type="radio"
        width="55"
        align="center"
      />
      <!-- 是否需要序号 -->
      <vxe-column
        v-if="index && !isTree"
        :fixed="props.isExpand ? null : 'left'"
        type="seq"
        title="序号"
        width="60"
      />
      <!-- 是否需要展开行 -->
      <vxe-column v-if="isExpand" type="expand" width="80">
        <template #content="{ row }">
          <slot name="expand" :item="row" />
        </template>
      </vxe-column>
      <!-- 渲染 逻辑 -->
      <template
        v-for="(columnItem, index) in tableColumn"
        :key="`p-table-${columnItem.prop}-${index}`"
      >
        <!-- fixed  -->
        <vxe-column
          v-if="!columnItem.isColgroup"
          :fixed="getFixed(columnItem)"
          :title="columnItem.label"
          :field="columnItem.prop"
          :rules="columnItem.rules"
          :tree-node="columnItem.treeNode"
          :width="
            columnItem.width !== undefined
              ? columnItem.width
              : columnItem.label.includes('单号') ||
                columnItem.label.includes('物资编码') ||
                columnItem.label.includes('物资名称') ||
                columnItem.label.includes('服务编码') ||
                columnItem.label.includes('服务名称')
              ? '180'
              : columnItem.label == '操作'
              ? '240'
              : 'auto'
          "
          :show-overflow="
            columnItem.showText === undefined
              ? isShowText(columnItem)
              : columnItem.showText
          "
          :edit-render="editRender(columnItem)"
        >
          <template #header>
            <!-- draggable="true"
              v-bind:ondragstart="drag(event)"
              v-bind:ondrop="drop(event)"
              v-bind:ondragover="allowDrop(event)" -->
            <div>
              {{ columnItem.label }}
            </div>
          </template>
          <!--   -->
          <template #default="scope">
            <slot
              name="columnCell"
              :record="scope.row"
              :scope="scope"
              :column="{
                prop: columnItem.prop,
                label: columnItem.label,
                width: columnItem.width,
              }"
              >{{ getData(scope.row, columnItem.prop, columnItem.label) }}</slot
            >
          </template>

          <!-- 表格编辑所用插槽 -->
          <template #edit="scope">
            <slot
              name="edit"
              :record="scope.row"
              :scope="scope"
              :column="{
                prop: columnItem.prop,
                label: columnItem.label,
                width: columnItem.width,
              }"
              >{{ getData(scope.row, columnItem.prop, columnItem.label) }}</slot
            >
          </template>
        </vxe-column>
      </template>
      <!-- 开发环境使用 线上自动取消 -->
      <template #empty v-if="isShow">
        <span style="color: red">
          <img
            src="https://pic2.zhimg.com/50/v2-f7031359103859e1ed38559715ef5f3f_hd.gif"
          />
          <p>不用再看了，没有更多数据了！</p>
        </span>
      </template>
    </vxe-table>
    <div
      v-if="isPage && totalCon > 0"
      class="pagination-container"
      :class="{ hidden: hidden }"
      id="paginationId"
    >
      <el-pagination
        :background="background"
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :layout="layout"
        :page-sizes="pageSizes"
        :pager-count="pagerCount"
        :total="totalCon"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>
<style scoped lang="scss">
.p-table {
  position: relative;
  width: 100%;
  height: 100%;
  .p-table-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
}

.pagination-container {
  // z-index: 22;
  display: flex;
  justify-content: center;
  align-items: center;
  //position: fixed;
  bottom: 1.25rem;
  width: 100%;
}
.fixed {
  position: absolute;
  bottom: 0px;
  height: 2rem;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.pagination-container.hidden {
  display: none;
}
#paginationId ::v-deep .el-input__inner {
  width: 100px !important;
}
#paginationId ::v-deep .el-input {
  width: 100px !important;
}
#paginationId ::v-deep .el-select--default {
  width: 100px !important;
}

.tableClass {
  width: 100% !important;
  margin-top: 0.9375rem;
}

// 操作
.x {
  position: absolute;
  top: -2.8125rem;
  right: 0;
}

.tableClass ::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

/*滚动条的轨道*/
.tableClass ::-webkit-scrollbar-track {
  background-color: #ffffff;
}

/*滚动条里面的小方块，能向上向下移动*/
// .tableClass ::-webkit-scrollbar-thumb {
//   background-color: #bfbfbf;
//   border-radius: 5px;
//   border: 1px solid #f1f1f1;
//   box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
// }

// .tableClass ::-webkit-scrollbar-thumb:hover {
//   background-color: #a8a8a8;
// }

// .tableClass ::-webkit-scrollbar-thumb:active {
//   background-color: #787878;
// }

// /*边角，即两个滚动条的交汇处*/
// .tableClass ::-webkit-scrollbar-corner {
//   background-color: #ffffff;
// }

// .tableClass ::v-deep .col-blue {
//   background-color: #2db7f5;
//   color: #fff;
// }
// .tableClass ::v-deep .col-red {
//   background-color: red;
//   color: #fff;
// }
</style>
